﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using ScrumTable.Common.Collections;
using ScrumTable.DL.Data.Generic.Cache;
using ScrumTable.DL.Data.TFS.Services.TeamFoundation;
using ScrumTable.DL.Data.TFS.Services.TeamFoundation.Utils;

#endregion

namespace ScrumTable.DL.Data.TFS.Bulk.Services
{
    /// <summary>
    /// This class is used to initiate the connection and load all needed
    /// information to access data on the project level.
    /// </summary>
    internal partial class ConnectionCacheLoader
    {
        #region Declarations

        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------

        #endregion

        #region Properties

        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        #endregion

        #region Constructors / Destructor

        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        #endregion

        #region Methods

        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        partial void LoadMemberList(
            ref IList<CacheTeam> teamListToInit, 
            ref IList<CacheMember> memberListToInit,
            TfsServerWrapper tfsInstance,
            CacheContext dataContext,
            Project project)
        {
            teamListToInit = new List<CacheTeam>();

            // dictionary structure = [ MEMBER_UNIQUE_ID -> (MEMBER, TEAM_IDs) ]
            IDictionary<string, Pair<TeamFoundationIdentity, IList<string>>> memberByTeamIdx = new Dictionary<string, Pair<TeamFoundationIdentity, IList<string>>>();
            
            // Retrieve a list of all teams on the project.
            foreach (TeamFoundationTeam team in tfsInstance.TfsTeamService.QueryTeams(project.Uri.ToString()))
            {
                teamListToInit.Add(dataContext.ElementFactory.CreateTeam(teamListToInit.Count, team.Name, team.Identity.DisplayName));

                foreach (TeamFoundationIdentity teamMemberId in QueryMembers(team.GetMembers(tfsInstance.NativeConnection, MembershipQuery.Expanded)))
                {
                    if (!memberByTeamIdx.ContainsKey(teamMemberId.GetUniqueId()))
                    {
                        memberByTeamIdx[teamMemberId.GetUniqueId()] = new Pair<TeamFoundationIdentity, IList<string>>(
                            team.Identity,
                            new List<string>());
                    }

                    memberByTeamIdx[teamMemberId.GetUniqueId()].Right.Add(team.Identity.DisplayName);
                }
            }

            memberListToInit = ConvertToMembersList(memberByTeamIdx, dataContext, project);
        }

        private IList<CacheMember> ConvertToMembersList(
            IDictionary<string, Pair<TeamFoundationIdentity, IList<string>>> memberByTeamIdx,
            CacheContext dataContext,
            Project project)
        {
            IList<CacheMember> memberList = new List<CacheMember>();
            double orderIndex = 0;

            foreach (TeamFoundationIdentity identity in QueryMembers(MemberLoader.GetMembers(GetAssignedToValues(project))))
            {
                memberList.Add(dataContext.ElementFactory.CreateMember(
                    ++orderIndex,
                    identity.DisplayName,
                    identity.GetAttribute(IdentityAttributeTags.MailAddress, string.Empty),
                    identity.GetAttribute(IdentityAttributeTags.AccountName, string.Empty),
                    identity.GetAttribute(IdentityAttributeTags.Domain, string.Empty),
                    identity.GetUniqueId(),
                    _connectionCtx.Contains(identity.GetUniqueId()),
                    memberByTeamIdx.ContainsKey(identity.GetUniqueId()) ? memberByTeamIdx[identity.GetUniqueId()].Right : null));
            }
            return memberList;
        }

        private IEnumerable<TeamFoundationIdentity> QueryMembers(IEnumerable<TeamFoundationIdentity> toFillIn)
        {
            return (from identity in toFillIn 
                    where (!identity.IsContainer && identity.GetUniqueId() != null)
                    select identity);
        }

        #endregion

        #region Events

        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        #endregion
    }
}